package generador;

import java.util.Iterator;

import manager.INodeData;
import utils.Tree;
import utils.TreeNode;

public class GeneradorCodigo2 {

	//Arbol raiz;
	Tree<INodeData> raiz;
	TablaSimbolo tablaSimbolo;
	TablaTemporal tablaTemporal;
	int indexLiteral;
	int indexTag;
	int indexTemporal;
	private static final int INDEX_MAIN = 3;

	public GeneradorCodigo2(Tree<INodeData> arbolPrograma, TablaSimbolo tablaSimbolo) {
		raiz = arbolPrograma;
		this.tablaSimbolo = tablaSimbolo;
		this.tablaTemporal = new TablaTemporal();
		indexLiteral = 0;
		indexTag = 0;
		indexTemporal = 0;
	}


	public String generarCodigo() {
		StringBuilder codigo = new StringBuilder();
		codigo.append("ORG 100h \n");
		codigo.append("JMP Comienzo \n");
		String programa = procesarArbol();
		codigo.append(tablaTemporal.getCodigoTablaTemporal());
		codigo.append("Comienzo: \n");
		codigo.append(programa);
		codigo.append(GeneradorDeRutinas.getRutinasFijas());
		return codigo.toString();
	}

	private String procesarArbol() {
		int i=0,indxmain=0;
		StringBuilder codigoRaiz = new StringBuilder();
		TreeNode<INodeData> arbolHijo = raiz.getRoot();
		TreeNode<INodeData> arbolcodigo = arbolHijo.getChildren().get(1);

		Iterator<TreeNode<INodeData>> it = arbolcodigo.getChildren().iterator();
		TreeNode<INodeData> arbolit = null;
		
		while (it.hasNext()) {
			
			arbolit = it.next();
			Integer busvarmin = arbolit.toString().indexOf(":") +2 ;
			Integer busvarmax = arbolit.toString().indexOf("(")  ;
			if 	(arbolit.getData().toString().substring(busvarmin,busvarmax).trim().equalsIgnoreCase("main")) {
					indxmain= i;
			}
			i=i+1;
		}
		
		TreeNode<INodeData> arbolmain = arbolcodigo.getChildren().get(indxmain);
		codigoRaiz.append(getCodigoMetodo(arbolmain.getChildren().get(INDEX_MAIN)));
		codigoRaiz.append("mov ax, 4c00h \n");
		codigoRaiz.append("int 21h \n");
		indxmain=0;
		i=0;
		it = arbolcodigo.getChildren().iterator();
		
		while (it.hasNext()) {
			
			arbolit = it.next();
			Integer busvarmin = arbolit.toString().indexOf(":") +2 ;
			Integer busvarmax = arbolit.toString().indexOf("(")  ;

			if 	(!arbolit.getData().toString().substring(busvarmin,busvarmax).trim().equalsIgnoreCase("main"))  {
				
				codigoRaiz.append(getCodigoProcedimiento(arbolit));
				
			}
			i=i+1;
		}

		//}
		
		return codigoRaiz.toString();
	
	}

	private String getCodigoMetodo(TreeNode<INodeData> arbolMain) {
		StringBuilder codigoMain = new StringBuilder();
		
		if (arbolMain.getChildren().size() > 0) {
			Iterator<TreeNode<INodeData>> it = arbolMain.getChildren().iterator();
			TreeNode<INodeData> arbolHijo = null;
			while (it.hasNext()) {
				arbolHijo = it.next();
				if (arbolHijo.getData() != null) {
				codigoMain.append(getCodigoInstruccion(arbolHijo));
				}
			}
		}
		return codigoMain.toString();
	}
	


	private String getCodigoInstruccion(TreeNode<INodeData> arbolInstruccion) {
		StringBuilder codigoInstrucciones = new StringBuilder();
	
		if (arbolInstruccion.getData().toString().equalsIgnoreCase(
				TiposConstantes.ASIGNACION)) {
			codigoInstrucciones.append(getCodigoAsignacion(arbolInstruccion));
		}
		if (arbolInstruccion.getData().toString().equalsIgnoreCase(TiposConstantes.CALL)) {
			codigoInstrucciones.append(getCodigoLlamada(arbolInstruccion.getChildren().get(0)));
		}
		if (arbolInstruccion.getData().toString().equalsIgnoreCase(TiposConstantes.MOSTRAR)) {
			codigoInstrucciones.append(getCodigoMostrar(arbolInstruccion));
		}
		if (arbolInstruccion.getData().toString().equalsIgnoreCase(TiposConstantes.MOSTRARLN)) {
			codigoInstrucciones.append(getcodigoMostrarln(arbolInstruccion));
		}
		if (arbolInstruccion.getData().toString().equalsIgnoreCase(TiposConstantes.SI)) {
			codigoInstrucciones.append(getCodigoSi(arbolInstruccion));
		}
		if (arbolInstruccion.getData().toString().equalsIgnoreCase(TiposConstantes.MIENTRAS)) {
			codigoInstrucciones.append(getCodigoMientras(arbolInstruccion));
		}
		if (arbolInstruccion.getData().toString().equalsIgnoreCase(TiposConstantes.LEER)) {
			codigoInstrucciones.append(getCodigoLeer(arbolInstruccion));
		}

		return codigoInstrucciones.toString();
	}
	
		private String getCodigoLeer(TreeNode<INodeData> arbolLeer) {
		StringBuilder codigoLeer = new StringBuilder();
		codigoLeer.append("push 0000h \n");
		codigoLeer.append("call readln \n");
		codigoLeer.append("pop ax \n");
		codigoLeer.append("mov " + getValorInternoDeID(arbolLeer.getChildren().get(0))
				+ ", ax \n");
		return codigoLeer.toString();
	}

	// TODO Esta comentado el ADD a la tabla de simbolos
	private String getValorInternoDeID(TreeNode<INodeData> arbol) {
		Integer busvarmax;

		//busvarmax = arbol.toString().length();
		//if (arbol.toString().substring(0, busvarmax).equalsIgnoreCase(TiposConstantes.NUMERO)) {
		if (arbol.toString().substring(0, 6).equalsIgnoreCase(TiposConstantes.NUMERO)) {
			
			Integer saconum =arbol.toString().indexOf(":") + 2;
			String num =arbol.toString().substring(saconum, arbol.toString().length());
			
			return num.trim() ;

		} else {
		
		Integer busvarmin = arbol.toString().indexOf(":") +2 ;
		
			if ( (busvarmax = arbol.toString().indexOf("(") -1) < -1) {
					busvarmax =arbol.toString().length();
			}
		
		String nombreInterno = "v_" + arbol.toString().substring(busvarmin,busvarmax).trim() + "_";
			this.tablaTemporal.agregarTemporal(nombreInterno, "0", "dw");
			return nombreInterno;
		}
		//}
	}

	private String getCodigoMientras(TreeNode<INodeData> arbolWhile) {
		StringBuilder codigoMientras = new StringBuilder();
		String tag = getValorDeTag();
		codigoMientras.append(tag + ": \n");
		String tagSigo = getValorDeTag();
		codigoMientras.append(getCodigoCondicion(arbolWhile, tagSigo));
		if (arbolWhile.getChildren().size() > 1) {
			TreeNode<INodeData> arbolMain = arbolWhile.getChildren().get(1);
			codigoMientras.append(getCodigoMetodo(arbolMain));
		}
		codigoMientras.append("jmp " + tag + " \n");
		codigoMientras.append(tagSigo + ": \n");
		return codigoMientras.toString();
	}

	private String getCodigoCondicion(TreeNode<INodeData> arbol, String tag) {
		StringBuilder codigoCondicion = new StringBuilder();
		TreeNode<INodeData> arbolOperador = arbol.getChildren().get(0);
		Integer abLength = arbolOperador.getData().toString().length();
		if (arbolOperador.getData().toString().substring(3, abLength).equalsIgnoreCase(TiposConstantes.IMPAR)
				|| arbolOperador.getData().toString().substring(3, abLength).equalsIgnoreCase(
						TiposConstantes.PAR)) {
			codigoCondicion.append(getCodigoExpresion(arbolOperador.getChildren()
					.get(0)));
			codigoCondicion.append("mov bx, 2 \n"); 
			codigoCondicion.append("mov dx, 0 \n");
			codigoCondicion.append("idiv bx \n");
			codigoCondicion.append("cmp dx, 0 \n");
			if (arbol.getChildren().size() > 2 ){ 
				tag="ELSE_" + tag;
			}
			
			if (arbolOperador.getData().toString().substring(3, abLength).equalsIgnoreCase(TiposConstantes.IMPAR)) {
				codigoCondicion.append("je " + tag + " \n");
			} else {
				codigoCondicion.append("jne " + tag + " \n");
			}
		} else {
			codigoCondicion.append(getCodigoExpresion(arbolOperador.getChildren().get(0)));
			codigoCondicion.append("mov cx, ax \n");
			codigoCondicion.append(getCodigoExpresion(arbolOperador.getChildren().get(1)));
			codigoCondicion.append("mov bx, ax \n");
			codigoCondicion.append("mov ax, cx \n");
			codigoCondicion.append("cmp ax, bx \n");
			
			if (arbol.getChildren().size() > 2 ){ 
				tag="ELSE_" + tag;
			}
			
			String  strCondicion =arbolOperador.getData().toString().substring(9,abLength).trim();
			
			if (strCondicion.equalsIgnoreCase(TiposConstantes.IGUAL)) {
				codigoCondicion.append("jne " + tag + " \n");
			}
			if (strCondicion.equalsIgnoreCase(TiposConstantes.MAYOR)) {
				codigoCondicion.append("jle " + tag + " \n");
			}
			if (strCondicion.equalsIgnoreCase(TiposConstantes.MENOR)) {
				codigoCondicion.append("jge " + tag + " \n");
			}
			if (strCondicion.equalsIgnoreCase(TiposConstantes.MAYOR_IGUAL)) {
				codigoCondicion.append("jl " + tag + " \n");
			}
			if (strCondicion.equalsIgnoreCase(TiposConstantes.MENOR_IGUAL)) {
				codigoCondicion.append("jg " + tag + " \n");
			}
		}
		return codigoCondicion.toString();
	}

	private String getCodigoExpresion(TreeNode<INodeData> arbol) {
		StringBuilder codigoExpresion = new StringBuilder();
		String tempActual;
		
		Integer maxCadena = arbol.getData().toString().length();
		String test = arbol.getData().toString().substring(0,maxCadena);
		
		if (!test.equalsIgnoreCase("call") ) {

		if (arbol.toString().equalsIgnoreCase(TiposConstantes.IDENTIFICADOR) || 
			arbol.toString().substring(0,8).equalsIgnoreCase("VARIABLE")	 ||
			arbol.toString().substring(0,9).equalsIgnoreCase("PARAMETRO")	 
			) {
			codigoExpresion.append("mov ax, " + getValorInternoDeID(arbol)
					+ " \n");
			}
		
		//String test = arbol.toString().substring(0, 6); --Obtengo la palabra NUMERO
		
		if (arbol.toString().substring(0, 6).equalsIgnoreCase(TiposConstantes.NUMERO)) {
	
			Integer saconum =arbol.toString().indexOf(":") + 2;
			String num =arbol.toString().substring(saconum, arbol.toString().length());
			
			codigoExpresion.append("mov ax, " + num.trim() + " \n");

		}
		if (arbol.toString().substring(0, 8).equalsIgnoreCase(TiposConstantes.PRODUCTO)) {
			codigoExpresion.append(getCodigoOperacion(arbol));
			tempActual = obtenerTemporalActual();
			codigoExpresion.append("mov bx, " + tempActual + " \n");
			codigoExpresion.append("imul bx \n");
			liberarTemporal();
		}
 
		if (arbol.toString().substring(0, 4).equalsIgnoreCase(TiposConstantes.SUMA)) {
			codigoExpresion.append(getCodigoOperacion(arbol));
			tempActual = obtenerTemporalActual();
			codigoExpresion.append("mov bx, " + tempActual + " \n");
			codigoExpresion.append("add ax, bx \n");
			liberarTemporal();
		}
		if (arbol.toString().substring(0, 5).equalsIgnoreCase(TiposConstantes.RESTA)) {
			codigoExpresion.append(getCodigoOperacion(arbol));
			tempActual = obtenerTemporalActual();
			codigoExpresion.append("mov bx, " + tempActual + " \n");
			codigoExpresion.append("sub ax, bx \n");
			liberarTemporal();
		}
		if (arbol.toString().substring(0, 8).equalsIgnoreCase(TiposConstantes.DIVISION)) {
			{
				codigoExpresion.append(getCodigoOperacion(arbol));
				tempActual = obtenerTemporalActual();
				codigoExpresion.append("mov bx, " + tempActual + " \n");
				codigoExpresion.append("mov dx, 0 \n");
				codigoExpresion.append("idiv bx \n");
				liberarTemporal();
			}
		}
		} else {
			if (arbol.getChildren().size()<3){ //Leo los parametros de una funcion o procedimiento
				Integer i=0;
				TreeNode<INodeData> arbolMainParam = raiz.getRoot().getChildren().get(1).getChildren().get(1).getChildren().get(0);
				TreeNode<INodeData> arbolParam = arbol.getChildren().get(1);
				Iterator<TreeNode<INodeData>> it = arbolParam.getChildren().iterator();
				TreeNode<INodeData> arbolHijo = null;
				while (it.hasNext()) {
					arbolHijo = it.next();
					Integer busvarmin = arbolMainParam.getChildren().toString().indexOf("=") +1 ;
					Integer busvarmax = arbolMainParam.getChildren().toString().length()-1;

					String strReferencia = arbolMainParam.getChildren().toString().substring(busvarmin,busvarmax).trim();
						if (strReferencia.equalsIgnoreCase("BYREF")){
							codigoExpresion.append("mov " + getValorInternoDeID(arbolHijo)
									+ ", ax \n");
							codigoExpresion.append("mov [bp+12]" 
									+ ", ax \n");			
								
						} else {
					codigoExpresion.append(getCodigoExpresion(arbolHijo));
					codigoExpresion.append("push " + getValorInternoDeID(arbolMainParam.getChildren().get(i))
							+ " \n");
					codigoExpresion.append("mov " + getValorInternoDeID(arbolMainParam.getChildren().get(i))
							+ ", ax \n");
					tempActual = obtenerTemporalActual();
						if (!tempActual.equalsIgnoreCase("temp0")){
							codigoExpresion.append("push " + " temp1 \n");
						}
						}
					i=i+1;
				}
				codigoExpresion.append(getCodigoLlamada(arbol.getChildren().get(0)));
				i=0;
				while ( i < arbolMainParam.getChildren().size()) {
					Integer busvarmin = arbolMainParam.getChildren().toString().indexOf("=") +1 ;
					Integer busvarmax = arbolMainParam.getChildren().toString().length()-1;

					String strReferencia = arbolMainParam.getChildren().toString().substring(busvarmin,busvarmax).trim();
						if (strReferencia.equalsIgnoreCase("BYREF")){
							codigoExpresion.append("mov ax" 
									+ ", [bp+12] \n");
						} else {
							tempActual = obtenerTemporalActual();
							if (!tempActual.equalsIgnoreCase("temp0")){
								codigoExpresion.append("pop " + " temp1 \n");
							}
						 	codigoExpresion.append("pop " + getValorInternoDeID(arbolMainParam.getChildren().get(i))
						+ " \n");}
				i=i+1;
				}
			}
			//codigoExpresion.append(getCodigoLlamada(arbol.getChildren().get(0)));
		}
		return codigoExpresion.toString();
	}

		
	private void liberarTemporal() {
		if (indexTemporal > 0) {
			indexTemporal--;
		}
	}

	private String obtenerTemporalActual() {
		String ret = "temp" + String.valueOf(indexTemporal);
		return ret;
	}

	// TODO Esta comentado el ADD a la tabla de simbolos
	private String getCodigoOperacion(TreeNode<INodeData> arbol)  {
		StringBuilder codigoOperacion = new StringBuilder();
		TreeNode<INodeData> arbolOperIzq = arbol.getChildren().get(0);
		TreeNode<INodeData> arboloperDer = arbol.getChildren().get(1);
		codigoOperacion.append(getCodigoExpresion(arboloperDer));
		String temp = obtenerTemporal();
		this.tablaTemporal.agregarTemporal(temp, "0", "dw");
		codigoOperacion.append("mov " + temp + ", ax \n");
		codigoOperacion.append(getCodigoExpresion(arbolOperIzq));
		return codigoOperacion.toString();
	}

	private String obtenerTemporal() {
		indexTemporal++;
		String ret = "temp" + String.valueOf(indexTemporal);
		return ret;
	}

	private String getValorDeTag() {
		String ret = "tag" + String.valueOf(indexTag);
		indexTag++;
		return ret;
	}

	private String getCodigoSi(TreeNode<INodeData> arbolIf) {
		StringBuilder codigoSi = new StringBuilder();
		String tag = getValorDeTag();
		codigoSi.append(getCodigoCondicion(arbolIf, tag));
		if (arbolIf.getChildren().size() > 1) {
			TreeNode<INodeData> arbolMain = arbolIf.getChildren().get(1);
			codigoSi.append(getCodigoMetodo(arbolMain));
			codigoSi.append("jmp " + tag + "\n");
			if (arbolIf.getChildren().size() > 2) {
				arbolMain = arbolIf.getChildren().get(2);
				codigoSi.append("ELSE_"+ tag + ": \n");
				codigoSi.append(getCodigoMetodo(arbolMain));
				codigoSi.append("jmp " + tag + "\n");
			}
			
		}
		
		codigoSi.append(tag + ": \n");
		return codigoSi.toString();
	}

	private String getcodigoMostrarln(TreeNode<INodeData> arbol) {
		StringBuilder codigoMostrarln = new StringBuilder();
		codigoMostrarln.append(getCodigoMostrar(arbol));
		codigoMostrarln.append("call writeCRLF \n");
		return codigoMostrarln.toString();
	}

	// TODO Esta comentado el ADD a la tabla de simbolos
	private String getCodigoMostrar(TreeNode<INodeData> arbol) {
		StringBuilder codigoMostrar = new StringBuilder();
		Integer busvarmin;
		Iterator<TreeNode<INodeData>> it = arbol.getChildren().iterator();
		TreeNode<INodeData> arbolHijo = null;
		while (it.hasNext()) {
			arbolHijo = it.next();
			
			if (arbolHijo.toString().indexOf("null") < 0) {

				codigoMostrar.append("mov ax, " + getValorInternoDeID(arbolHijo)
						+ " \n");
				codigoMostrar.append("push ax \n");
				codigoMostrar.append("call writeNUM \n");
			} else {
				String codigoCadena = getValorDeLiteral();				
				
				busvarmin = arbolHijo.toString().indexOf("null") + 5 ;			
				Integer busvarmax = arbolHijo.toString().length()  ;
				String cadena = arbolHijo.toString().trim().substring(busvarmin, busvarmax);
				this.tablaTemporal.agregarTemporal(codigoCadena,cadena , "db");
				codigoMostrar.append("push offset " + codigoCadena + " \n");
				int push = (cadena.length() - 3);
				if (push <= 0) {
					push = 1;
				}
				codigoMostrar.append("push " + push + " \n");
				codigoMostrar.append("call writeSTR \n");
		
			}
		}
		return codigoMostrar.toString();
	}

	private String getValorDeLiteral() {
		String ret = "texto" + String.valueOf(indexLiteral);
		indexLiteral++;
		return ret;
	}

	private String getCodigoLlamada(TreeNode<INodeData> arbol) {
		StringBuilder codigoCall = new StringBuilder();
		TreeNode<INodeData> arbolCall = arbol.getParent();
		
		TreeNode<INodeData> arbolHijo = raiz.getRoot();
		TreeNode<INodeData> arbolcodigo = arbolHijo.getChildren().get(1);
		Iterator<TreeNode<INodeData>> it = arbolcodigo.getChildren().iterator();
		TreeNode<INodeData> arbolit = null;

		Integer busvarmin = arbol.toString().indexOf(":") +2 ;
		Integer busvarmax = arbol.toString().indexOf("(") ;
			
		String nombreCall = arbol.toString().substring(busvarmin, busvarmax).trim();
		String valorExp =null;
		Boolean CallExp=false;
		Integer i =0;
		
			while (it.hasNext()) {
				arbolit = it.next();

				if 	(arbolit.getData().toString().substring(busvarmin,busvarmax).trim().equalsIgnoreCase(nombreCall))  {
					
					Integer maxParam = arbolCall.getChildren().get(1).getChildren().size();
						while ( i < maxParam) {
							
							String Param1a=arbolCall.getChildren().get(1).getChildren().get(i).toString();
							String Param2a=arbolit.getChildren().get(0).getChildren().get(i).toString();
							Integer existeParam =Param1a.indexOf(":");
							//String Param1 = Param1a.toString().substring(0, Param1a.indexOf(":"));
							
							//if (( Param1.toString().equalsIgnoreCase("parametro") ) || (Param1.toString().equalsIgnoreCase("variable")))
							if (existeParam > 0) {
								codigoCall.append("mov ax, "
										+ getValorInternoDeID(arbolCall.getChildren().get(1).getChildren().get(i)) + " \n");
							} else{
								if (arbol.toString().substring(0, busvarmin).trim().equalsIgnoreCase("procedimiento:")){
								codigoCall.append(getCodigoExpresion(arbolCall.getChildren().get(1).getChildren().get(i)));
								codigoCall.append("push "
										+ getValorInternoDeID(arbolCall.getChildren().get(1).getChildren().get(i).getChildren().get(0)) + " \n");
								valorExp = getValorInternoDeID(arbolCall.getChildren().get(1).getChildren().get(i).getChildren().get(0)).toString();
								CallExp=true;
								codigoCall.append("mov "
										+ getValorInternoDeID(arbolCall.getChildren().get(1).getChildren().get(i).getChildren().get(0)) + ", ax \n");
									codigoCall.append("mov ax, "
										+ getValorInternoDeID(arbolCall.getChildren().get(1).getChildren().get(i).getChildren().get(0)) + " \n");
								}
							}
								codigoCall.append("mov "
										+ getValorInternoDeID(arbolit.getChildren().get(0).getChildren().get(i)) + ", ax \n");
								i=i+1;
								}
				}
				i = 0;
				
			}
				
			if (CallExp){
			codigoCall.append("call " + nombreCall + " \n");
			codigoCall.append("pop " + valorExp + " \n");
			} else {
				codigoCall.append("call " + nombreCall + " \n");
			}
		
		
		return codigoCall.toString();
	}

	private String getCodigoAsignacion(TreeNode<INodeData> arbolAsignacion) {
		StringBuilder codigoAsignacion = new StringBuilder();
		TreeNode<INodeData> arbolIdentificador = arbolAsignacion.getChildren().get(0);
		TreeNode<INodeData> arbolExpresion = arbolAsignacion.getChildren().get(1);;
		codigoAsignacion.append(getCodigoExpresion(arbolExpresion));
		codigoAsignacion.append("mov "
				+ getValorInternoDeID(arbolIdentificador) + ", ax \n");
		return codigoAsignacion.toString();
	}
	

	private String getCodigoProcedimientos(TreeNode<INodeData> arbolProcedimientos) {
		
		StringBuilder codigoProcedimientos = new StringBuilder();
		return codigoProcedimientos.toString();
	}

	private String getCodigoProcedimiento(TreeNode<INodeData> arbolProcedimiento) {
		StringBuilder codigoProcedimiento = new StringBuilder();
		
		Integer busvarmin = arbolProcedimiento.toString().indexOf(":") +2 ;
		Integer busvarmax = arbolProcedimiento.toString().indexOf("(")  ;
		String nombre =arbolProcedimiento.getData().toString().substring(busvarmin,busvarmax).trim();
				
		codigoProcedimiento.append(nombre + " proc near \n");
		TreeNode<INodeData> arbolVariables = arbolProcedimiento.getChildren().get(1);
		TreeNode<INodeData> arbolMain = arbolProcedimiento.getChildren().get(3);
		setCodigoVariables(arbolVariables);
		codigoProcedimiento.append(getCodigoMetodo(arbolMain));
			if (codigoProcedimiento.toString().equalsIgnoreCase(nombre + " proc near \n")){
				codigoProcedimiento.setLength(0);
			} else {
		codigoProcedimiento.append("ret \n");
		codigoProcedimiento.append(nombre + " endp \n");
			}
		return codigoProcedimiento.toString();
	}

	private void setCodigoVariables(TreeNode<INodeData> arbolVariables) {
		Iterator<TreeNode<INodeData>> it = arbolVariables.getChildren().iterator();
		TreeNode<INodeData> arbolVariable = null;
		while (it.hasNext()) {
			arbolVariable = it.next();
			setCodigoIdentificador(arbolVariable);
		}
	}

	// TODO Esta comentado el ADD a la tabla de simbolos
	private void setCodigoIdentificador(TreeNode<INodeData> arbolIdentificador) {
		String nombreInterno = getValorInternoDeID(arbolIdentificador);
	}
}

